#pragma once
#include <VersionHelpers.h>

namespace Utility {

    BOOL RegGetSZ(const WCHAR* lpSubKey, const WCHAR* lpValueName, WCHAR* wstr, int size, REGSAM samDesired) {
        DWORD type = REG_SZ;
        DWORD cbData = size;
        HKEY key;
        BOOL result = false;
        LONG res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpSubKey, 0, samDesired, &key);
        if (res == ERROR_SUCCESS) {
            res = RegQueryValueEx(key, lpValueName, NULL, &type, (LPBYTE)wstr, &cbData);
            if (res == ERROR_SUCCESS) {
                if (type == REG_SZ && size >= cbData)
                {
                    result = true;
                }
            }
            else {
            }
            RegCloseKey(key);
        }
        else {
        }
        return result;
    }

    BOOL RegGetDword(const WCHAR* lpSubKey, const WCHAR* lpValueName, DWORD* value, REGSAM samDesired) {
        DWORD type;
        BYTE data[4];
        DWORD cbData = 4;
        HKEY key;
        BOOL result = false;
        LONG res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpSubKey, 0, samDesired, &key);
        if (res == ERROR_SUCCESS) {
            res = RegQueryValueEx(key, lpValueName, NULL, &type, (LPBYTE)data, &cbData);
            if (res == ERROR_SUCCESS) {
                if (type == REG_DWORD)
                {
                    *value = *((PDWORD)data);
                    result = true;
                }
            }
            else {
            }
            RegCloseKey(key);
        }
        else {
        }
        return result;
    }

    std::string getWindowsVersion()
    {
        std::string windowsVersion;
        std::wstring version;
        // type
        bool isServer = IsWindowsServer();
        // CurrentMajorVersionNumber
        DWORD CurrentMajorVersionNumber;
        Utility::RegGetDword(L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", L"CurrentMajorVersionNumber", &CurrentMajorVersionNumber, KEY_READ);
        if (CurrentMajorVersionNumber == 10)
        {
            if (isServer) {
                // ProductName
                WCHAR ProductName[64];
                Utility::RegGetSZ(L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", L"ProductName", ProductName, sizeof(ProductName), KEY_READ);
                if (wcsstr(ProductName, L"2016"))
                {
                    windowsVersion = "2016";
                }
                else if (wcsstr(ProductName, L"2019"))
                {
                    windowsVersion = "2019";
                }
            }
            else {
                windowsVersion = "10.0";
            }
        }
        else
        {
            // CurrentVersion
            WCHAR CurrentVersion[16];
            Utility::RegGetSZ(L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", L"CurrentVersion", CurrentVersion, sizeof(CurrentVersion), KEY_READ);
            if (wcslen(CurrentVersion) >= 3)
            {
                version = std::wstring(CurrentVersion).substr(0, 3);
                if (version.compare(L"5.0") == 0)
                {
                    windowsVersion = "2000";
                }
                else if (version.compare(L"5.1") == 0)
                {
                    windowsVersion = "XP";
                }
                else if (version.compare(L"5.2") == 0)
                {
                    windowsVersion = "2003";
                }
                else if (version.compare(L"6.0") == 0)
                {
                    if (isServer)
                        windowsVersion = "2008";
                    else
                        windowsVersion = "Vista";
                }
                else if (version.compare(L"6.1") == 0)
                {
                    if (isServer)
                        windowsVersion = "2008R2";
                    else
                        windowsVersion = "7";
                }
                else if (version.compare(L"6.2") == 0)
                {
                    if (isServer)
                        windowsVersion = "2012";
                    else
                        windowsVersion = "8";
                }
                else if (version.compare(L"6.3") == 0)
                {
                    if (isServer)
                        windowsVersion = "2012R2";
                    else
                        windowsVersion = "8.1";
                }
                else if (version.compare(L"6.4") == 0)
                {
                    if (isServer)
                        windowsVersion = "2016";
                    else
                        windowsVersion = "10.0";
                }
            }
        }

        return windowsVersion;
    }
}